package mail.security;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import com.sun.crypto.provider.AESKeyGenerator;

public class SecurityManager {
  private static final byte[] KEYDATA = {11, 3, 55, 16, 7, 4, 1, 20};
  private static final String CHARSET = "UTF-8";
  private static final String ALGORITHM = "DES";
  
  
  public static String encryptDES(String raw) {
    byte[] en = encryptDES(raw.getBytes());
    char[] a = toCharArray(en);
    return new String(a);
  }
  
  public static String decryptDES(String encrypt) {
    char[] a = encrypt.toCharArray();
    byte[] en = toByteArray(a);
    byte[] raw = decryptDES(en);
    return new String(raw);
  }
  
  public static byte[] encryptDES(byte[] raw) {
    ByteArrayInputStream bais = null;
    ByteArrayOutputStream baos = null;
    try {
      SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
      DESKeySpec keySpec = new DESKeySpec(KEYDATA);
      Key key = factory.generateSecret(keySpec);
      Cipher cipher = Cipher.getInstance(ALGORITHM);
      cipher.init(Cipher.ENCRYPT_MODE, key);
      bais = new ByteArrayInputStream(raw);
      baos = new ByteArrayOutputStream();
      crypt(bais, baos, cipher);
      byte[] encryptString = baos.toByteArray();
      return encryptString;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }finally {
      try {
        bais.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
      try {
        baos.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  
  public static byte[] decryptDES(byte[] encrypt) {
    ByteArrayInputStream bais = null;
    ByteArrayOutputStream baos = null;
    try {
      SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
      DESKeySpec keySpec = new DESKeySpec(KEYDATA);
      Key key = factory.generateSecret(keySpec);
      Cipher cipher = Cipher.getInstance(ALGORITHM);
      cipher.init(Cipher.DECRYPT_MODE, key);
      bais = new ByteArrayInputStream(encrypt);
      baos = new ByteArrayOutputStream();
      crypt(bais, baos, cipher);
      byte[] raw = baos.toByteArray();
      return raw;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }finally {
      try {
        bais.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
      try {
        baos.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  
  private static void crypt(InputStream is, OutputStream os, Cipher cipher) {
    int blockSize = cipher.getBlockSize();
    int outputSize = cipher.getOutputSize(blockSize);
    byte[] in = new byte[blockSize];
    byte[] out = new byte[outputSize];
    boolean more = true;
    int length = 0;
    try {
      while(more) {
        length = is.read(in);
        if(length == blockSize) {
          out = cipher.update(in, 0, blockSize);
          os.write(out);
        }else {
          more = false;
        }
      }
      if(length > 0) {
        out = cipher.doFinal(in, 0, length);
      } else{
        out = cipher.doFinal();
      }
      os.write(out);
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
  
  public static char[] toCharArray(byte[] src) {
    char[] tmp = new char[src.length];
    for(int i=0; i<src.length; i++) {
      tmp[i] = (char)src[i];
    }
    return tmp;
  }
  
  public static byte[] toByteArray(char[] src) {
    byte[] tmp = new byte[src.length];
    for(int i=0; i<src.length; i++) {
      tmp[i] = (byte)src[i];
    }
    return tmp;
  }
  
  public static void main(String[] args) {
    try {
      String encrypt = SecurityManager.encryptDES("zjy@801229 ");
      System.out.println(encrypt);
      System.out.println(SecurityManager.decryptDES(encrypt));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
